package com.taxshare.seller.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.XmlUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.taxshare.freemark.utils.FreemarkUtil;
import com.taxshare.mybatis.pager.PageInfoRequest;
import com.taxshare.mybatis.pager.PageRequest;
import com.taxshare.response.beans.Response;
import com.taxshare.seller.constant.CodeConstant;
import com.taxshare.seller.constant.ResultConstant;
import com.taxshare.seller.entity.*;
import com.taxshare.seller.mapper.RemainderInvoiceMapper;
import com.taxshare.seller.mapper.StockDetailMapper;
import com.taxshare.seller.remote.ApiClientService;
import com.taxshare.seller.service.sst.IntJsonUtil;
import com.taxshare.seller.util.InvoiceHelper;
import com.taxshare.seller.util.TransformationUtil;
import com.taxshare.seller.view.dto.InterfaceDTO;
import com.taxshare.seller.view.dto.SellerInvoiceDTO;
import com.taxshare.seller.view.dto.StockDetailDTO;
import com.taxshare.seller.view.vo.StockDetailVO;
import com.taxshare.seller.view.vo.SyncBlankInvoiceDTO;
import com.taxshare.tools.util.DateUtil;
import com.taxshare.tools.util.UUIDUitl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @ClassName: StockDetailService
 * @Description: 发票领购查询
 * @author: hjh
 * @date: 2021/5/31 17:52
 */
@Service
@Slf4j
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
public class StockDetailService extends ServiceImpl<StockDetailMapper, StockDetailEntity> {

    @Autowired
    ApiClientService apiClientService;

    @Autowired
    BlankInvoiceWarningService blankInvoiceWarningService;

    @Autowired
    EquipmentService equipmentService;

    @Value("${zzsfp.url}")
    private String zzsfpUrl;

    @Autowired
    CommService commService;

    @Autowired
    RemainderInvoiceMapper remainderInvoiceMapper;

    /**
     * 发票领购查询（库存）
     *
     * @return
     */
    public Response queryStockDetail(PageRequest<StockDetailDTO> query) {
        StockDetailDTO info = query.getInfo();
        PageInfoRequest page = query.getPage();
        QueryWrapper<StockDetailEntity> queryWrapper = new QueryWrapper<>();
        if (!StrUtil.hasBlank(info.getSellerTaxNo())) {
            queryWrapper.eq("seller_tax_no", info.getSellerTaxNo());
        }else {
            List<String> taxNos = commService.getTaxNumbers();
            queryWrapper.in("seller_tax_no", taxNos);
        }
        IPage<StockDetailVO> result =
                baseMapper.selectStockDetails(new Page<>(page.getCurrentPage(), page.getPageSize()), queryWrapper);
        result.getRecords().stream().forEach(
                item -> item.setInvoiceTypeNo(InvoiceHelper.ptransFplxdm(item.getInvoiceTypeNo()))
        );
        return Response.success(result);
    }

    /**
     * 发票库存管理（库存）
     *
     * @return
     */
    public Response queryRemainderDetail(PageRequest<StockDetailDTO> query) {
        StockDetailDTO info = query.getInfo();
        PageInfoRequest page = query.getPage();
        QueryWrapper<RemainderInvoiceEntity> queryWrapper = new QueryWrapper<>();
        if (!StrUtil.hasBlank(info.getSellerTaxNo())) {
            queryWrapper.eq("seller_tax_no", info.getSellerTaxNo());
        }else {
            List<String> taxNos = commService.getTaxNumbers();
            queryWrapper.in("seller_tax_no", taxNos);
        }
        IPage<StockDetailVO> result =
                remainderInvoiceMapper.queryRemainderDetail(new Page<>(page.getCurrentPage(), page.getPageSize()), queryWrapper);
        result.getRecords().stream().forEach(
                item -> item.setInvoiceTypeNo(InvoiceHelper.ptransFplxdm(item.getInvoiceTypeNo()))
        );
        return Response.success(result);
    }

    /**
     * 同步库存明细
     *
     * @return
     */
    public Response syncStockDetail(SyncBlankInvoiceDTO syncBlankInvoiceDTO) {
        String sellerTaxNo = syncBlankInvoiceDTO.getSellerTaxNo();
        String syncType = syncBlankInvoiceDTO.getSyncType();
        Response response = new Response();
        if (StrUtil.hasBlank(sellerTaxNo)) {
            return Response.error(ResultConstant.RET_P0001_CODE, ResultConstant.RET_P0001_MSG);
        }
        EquipmentEntity entity = equipmentService.getOne(new QueryWrapper<EquipmentEntity>().eq("seller_tax_no", sellerTaxNo));
        if (entity == null || CodeConstant.COMM_CODE_0.equals(entity.getDisable())) {
            return Response.error("SEL_038");
        }
        if (CodeConstant.A9.equals(entity.getEquipmentMode())) {
            response = syncStockDetailA9(sellerTaxNo);
        } else {
            response = syncInventoryInvoiceSST(entity,syncType);
        }
        return response;
    }

    /**
     * 同步库存明细(A9)
     *
     * @return
     */
    public Response syncStockDetailA9(String nsr) {
        Response<Object> res = new Response<>();
        Map<String, String> fmap = new HashMap<>();
        fmap.put("fplx", "");
        String syncStockDetail = FreemarkUtil.getTemplateObj("syncStockDetail.ftl", fmap);
        String url = zzsfpUrl + "kcmxcxInterface";
        String interfaceCode = "EI.KCMXCX.U.EC.INTRA";
        String xmlData = InvoiceHelper.getXmlData(syncStockDetail, interfaceCode, nsr, null);
        InterfaceDTO interfaceDTO = new InterfaceDTO();
        interfaceDTO.setXmlData(xmlData);
        interfaceDTO.setUrl(url);
        Response response = apiClientService.callSales(interfaceDTO);
        if (CodeConstant.T0000.equals(response.getCode())) {
            String data = (String) response.getData();
            Map<String, Object> map = XmlUtil.xmlToMap(data);
            try {
                SyncStockDetail(map);
            } catch (Exception e) {
                log.info("同步库存解析出现错误，请稍后重试！", e.getMessage());
                return Response.error(CodeConstant.T0001, "同步库存解析出现错误，请稍后重试！");
            }
        } else {
            res.setCode(response.getCode());
            res.setMsg(response.getMsg());
            return res;
        }
        return Response.success();
    }

    /**
     * 同步库存明细
     *
     * @param map
     */
    public void SyncStockDetail(Map map) {
        HashMap map1 = (HashMap) map.get("COMMON_KCMXCXS");
        Object obj = map1.get("COMMON_KCMXCX");
        StockDetailEntity stockDetailEntity = new StockDetailEntity();
        if (obj.getClass().isArray()) {
            ArrayList list = (ArrayList) obj;
            list.stream().forEach(item -> {
                Map<String, String> item1 = (HashMap) item;
                resolvingMap(stockDetailEntity, item1);
            });
        } else {
            HashMap<String, String> map2 = (HashMap<String, String>) map1.get("COMMON_KCMXCX");
            resolvingMap(stockDetailEntity, map2);
        }
    }

    /**
     * 同步库存明细(SST)
     *
     * @param entity
     * @return
     */
    public Response syncInventoryInvoiceSST(EquipmentEntity entity, String syncType) {
        String invoiceTypes = entity.getInvoiceTypeList();
        List<String> list = Arrays.asList(invoiceTypes.split(","));
        if (StrUtil.isBlank(invoiceTypes)) {
            return Response.error(CodeConstant.ERROR, "SEL_024");
        }
        //金税盘
        if (CodeConstant.JSP.equals(entity.getEquipmentMode())) {
            for (String invoiceType : list) {
                if (CodeConstant.COMM_CODE_0.equals(syncType)) {
                    String json = IntJsonUtil.blankInvoice(entity, "");
                    SellerInvoiceDTO sellerDTO = new SellerInvoiceDTO();
                    sellerDTO.setBw(json);
                    Response response = apiClientService.callSST(sellerDTO);
                    String result = (String) response.getData();
                    JSONObject jsonObject = (JSONObject) JSON.parse(result);
                    String code = jsonObject.getString("code");
                    String msg = jsonObject.getString("msg");
                    if (CodeConstant.THIRD_PARTY_SUCCESS.equals(code)) {
                        List<Map> resList = (List) jsonObject.get("data");
                        insertRemainderIncoice(resList, entity);
                        return Response.success();
                    } else {
                        return Response.error(code, msg);
                    }
                } else if (CodeConstant.COMM_CODE_1.equals(syncType)) {
                    String json = IntJsonUtil.remainderInvoice(entity, "");
                    SellerInvoiceDTO sellerDTO = new SellerInvoiceDTO();
                    sellerDTO.setBw(json);
                    Response response = apiClientService.callSST(sellerDTO);
                    String result = (String) response.getData();
                    JSONObject jsonObject = (JSONObject) JSON.parse(result);
                    String code = jsonObject.getString("code");
                    String msg = jsonObject.getString("msg");
                    if (CodeConstant.THIRD_PARTY_SUCCESS.equals(code)) {
                        List<Map> resList = (List) jsonObject.get("data");
                        insertInventoryInvoices(resList, entity, invoiceType);
                        return Response.success();
                    } else {
                        return Response.error(code, msg);
                    }
                }
            }

        } else {
            //税控盘、税务 key、税控服务器
            StringBuilder resMsg = new StringBuilder();
            try {
                if (!list.isEmpty() && list != null) {
                    if (CodeConstant.COMM_CODE_0.equals(syncType)) {
                        for (String invoiceType : list) {
                            String json = IntJsonUtil.blankInvoice(entity, invoiceType);
                            SellerInvoiceDTO sellerRemoteVo = new SellerInvoiceDTO();
                            sellerRemoteVo.setBw(json);
                            Response response = apiClientService.callSST(sellerRemoteVo);
                            String result = (String) response.getData();
                            JSONObject jsonObject = (JSONObject) JSON.parse(result);
                            String code = jsonObject.getString("code");
                            String msg = jsonObject.getString("msg");
                            if (CodeConstant.THIRD_PARTY_SUCCESS.equals(code)) {
                                List<Map> resList = (List) jsonObject.get("data");
                                insertRemainderIncoice(resList, entity);
//                            resMsg.append(IntJsonUtil.convertInvoiceTypeName(invoiceType) + "同步成功 ");
                            } else {
                                resMsg.append(IntJsonUtil.convertInvoiceTypeName(invoiceType) + "同步失败：" + msg);
                            }
                        }
                    } else if (CodeConstant.COMM_CODE_1.equals(syncType)) {
                        for (String invoiceType : list) {
                            String json = IntJsonUtil.remainderInvoice(entity, invoiceType);
                            SellerInvoiceDTO sellerRemoteVo = new SellerInvoiceDTO();
                            sellerRemoteVo.setBw(json);
                            Response response = apiClientService.callSST(sellerRemoteVo);
                            String result = (String) response.getData();
                            JSONObject jsonObject = (JSONObject) JSON.parse(result);
                            String code = jsonObject.getString("code");
                            String msg = jsonObject.getString("msg");
                            if (CodeConstant.THIRD_PARTY_SUCCESS.equals(code)) {
                                List<Map> resList = (List) jsonObject.get("data");
                                insertInventoryInvoices(resList, entity, invoiceType);
//                            resMsg.append(IntJsonUtil.convertInvoiceTypeName(invoiceType) + "同步成功 ");
                            } else {
                                resMsg.append(IntJsonUtil.convertInvoiceTypeName(invoiceType) + "同步失败：" + msg);
                            }
                        }
                    }
                }
            } catch (Exception e) {
                log.info("税控盘、税务 key、税控服务器 同步失败{}", e);
                return Response.error(CodeConstant.T0001, resMsg.toString());
            }
            if (StrUtil.isEmpty(resMsg)) {
                return Response.success();
            } else {
                return Response.error(CodeConstant.T0001, resMsg.toString());
            }
        }
        return Response.success();
    }

    /**
     * 空白发票领购(SST)
     */
    private void insertRemainderIncoice(List<Map> list, EquipmentEntity equipmentEntity) {
        if (CollUtil.isNotEmpty(list)) {
            for (Map m : list) {
                String invoiceCode = MapUtils.getString(m, "fpdm");
                String invoiceNoStart = MapUtils.getString(m, "fphm_q");
                String invoiceNoEnd = MapUtils.getString(m, "fphm_z");
                String invoiceType = MapUtils.getString(m, "fplxdm");
                QueryWrapper<StockDetailEntity> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("seller_tax_no", equipmentEntity.getSellerTaxNo());
                queryWrapper.eq("invoice_code", invoiceCode);
                queryWrapper.eq("invoice_no_start", invoiceNoStart);
                queryWrapper.eq("invoice_no_end", invoiceNoEnd);
                queryWrapper.eq("invoice_type_no", invoiceType);
                StockDetailEntity stockDetailEntity = new StockDetailEntity();
                if (baseMapper.selectCount(queryWrapper) > 0) {
                    stockDetailEntity.setInvoiceTotal(MapUtils.getString(m, "fs"));
                    this.update(stockDetailEntity, queryWrapper);
                } else {
                    stockDetailEntity.setUuid(UUIDUitl.UUID32());
                    stockDetailEntity.setSellerTaxNo(equipmentEntity.getSellerTaxNo());
                    stockDetailEntity.setSellerName(equipmentEntity.getSellerName());
                    stockDetailEntity.setPanNo(equipmentEntity.getPanNo());
                    stockDetailEntity.setInvoiceTypeNo(MapUtils.getString(m, "fplxdm"));
                    stockDetailEntity.setInvoiceCode(MapUtils.getString(m, "fpdm"));
                    stockDetailEntity.setPickDate(MapUtils.getString(m, "lgrq"));
                    stockDetailEntity.setInvoiceNoStart(invoiceNoStart);
                    stockDetailEntity.setInvoiceNoEnd(invoiceNoEnd);
                    stockDetailEntity.setInvoiceTotal(MapUtils.getString(m, "fs"));
                    String equipmentMode = equipmentEntity.getEquipmentMode();
                    if (CodeConstant.COMM_CODE_1.equals(equipmentMode)|| CodeConstant.COMM_CODE_2.equals(equipmentMode)){
                        stockDetailEntity.setBuyInvoiceState(MapUtils.getString(m, "gpzt"));
                    }
                    this.save(stockDetailEntity);
                }
            }
        }
    }

    /**
     * 保存余票信息(SST)
     */
    private void insertInventoryInvoices(List<Map> list, EquipmentEntity equipmentEntity,String invoiceType) {
        String equipmentMode = equipmentEntity.getEquipmentMode();
        String sellerTaxNo = equipmentEntity.getSellerTaxNo();
        String equipmentNo = equipmentEntity.getPanNo();
        QueryWrapper<RemainderInvoiceEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("seller_tax_no", sellerTaxNo);
        queryWrapper.eq("pan_no", equipmentNo);
        if (CodeConstant.SKP.equals(equipmentMode) || CodeConstant.UKEY.equals(equipmentMode)){
            queryWrapper.eq("invoice_type_no", invoiceType);
        }
        if (remainderInvoiceMapper.selectCount(queryWrapper)>0){
            remainderInvoiceMapper.delete(queryWrapper);
        }
        if (CollUtil.isNotEmpty(list)) {
            for (Map m : list) {
//                String invoiceCode = MapUtils.getString(m, "fpdm");
                String invoiceTypeNo = MapUtils.getString(m, "fplxdm");
                String pickDate = MapUtils.getString(m, "lgrq");
//                String transPickDate = DateUtil.getFormatDate(pickDate);
//                QueryWrapper<RemainderInvoiceEntity> queryWrapper = new QueryWrapper<>();
//                queryWrapper.eq("seller_tax_no", equipmentEntity.getSellerTaxNo());
//                queryWrapper.eq("invoice_code", invoiceCode);
//                queryWrapper.eq("invoice_type_no", invoiceType);
//                queryWrapper.eq("pan_no", equipmentNo);
//                queryWrapper.eq("pick_date",transPickDate);
                RemainderInvoiceEntity remainderInvoiceEntity = new RemainderInvoiceEntity();
                remainderInvoiceEntity.setUuid(UUIDUitl.UUID32());
                remainderInvoiceEntity.setSellerTaxNo(equipmentEntity.getSellerTaxNo());
                remainderInvoiceEntity.setSellerName(equipmentEntity.getSellerName());
                remainderInvoiceEntity.setPanNo(equipmentEntity.getPanNo());
                remainderInvoiceEntity.setInvoiceTypeNo(TransformationUtil.transSstInvoiceType(invoiceTypeNo));
                remainderInvoiceEntity.setInvoiceSheet(MapUtils.getString(m, "syfs"));
                remainderInvoiceEntity.setInvoiceCode(MapUtils.getString(m, "fpdm"));
                remainderInvoiceEntity.setPickDate(DateUtil.getFormatDate(pickDate));
                remainderInvoiceEntity.setInvoiceNoStart(MapUtils.getString(m, "qshm"));
                remainderInvoiceMapper.insert(remainderInvoiceEntity);
            }
        }
    }
    /**
     * 解析map并同步
     *
     * @param stockDetailEntity
     * @param map
     */
    private void resolvingMap(StockDetailEntity stockDetailEntity, Map<String, String> map) {
        stockDetailEntity.setInvoiceCode(map.get("FPDM"));
        stockDetailEntity.setFjh(map.get("FJH"));
        stockDetailEntity.setInvoiceNoStart(map.get("QSHM"));
        stockDetailEntity.setInvoiceSheet(map.get("FPFS"));
        stockDetailEntity.setInvoiceTypeNo(TransformationUtil.transSstInvoiceType(map.get("FPZL_DM")));
        stockDetailEntity.setSellerTaxNo(map.get("NSRSBH"));
        stockDetailEntity.setTerminalNo(map.get("ZDH"));
        QueryWrapper<StockDetailEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("invoice_code", map.get("FPDM"));
        queryWrapper.eq("invoice_no_start", map.get("QSHM"));
        queryWrapper.eq("seller_tax_no", map.get("NSRSBH"));
        StockDetailEntity entity = baseMapper.selectOne(queryWrapper);
        if (entity != null) {
            entity.setInvoiceSheet(map.get("FPFS"));
        } else {
            stockDetailEntity.setUuid(UUIDUitl.UUID32(false));
            this.save(stockDetailEntity);
        }
    }
}
